package org.dei.perla.sys.device.fpc;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Hashtable;

public class AbstractData {
	protected Hashtable<String, Method> gettersTable;
	protected Hashtable<String, Method> settersTable;

	public AbstractData() {
		gettersTable = new Hashtable<String, Method>();
		settersTable = new Hashtable<String, Method>();
		fillTables();
	}

	private void fillTables() {
		Method[] methods = this.getClass().getMethods();
		String name = "", tipoMetodo = "";
		for (Method m : methods) {
			name = m.getName();
			tipoMetodo = name.substring(0, 3);
			if (tipoMetodo.equals("get")) {
				gettersTable.put(name, m);
			} else if (tipoMetodo.equals("set")) {
				settersTable.put(name, m);
			}
		}
	}

	public Object lookForParameter(String parName)
			throws IllegalArgumentException, IllegalAccessException,
			InvocationTargetException {
		int i = 0;
		Object parameter = null;
		AbstractData compositeField = null;
		AbstractData[] compositeFieldArray = null;
		do {
			if (parName.charAt(i) == '_') {

					compositeField = (AbstractData) gettersTable.get(
							"get" + parName.substring(0, i)).invoke(this,
							(Object[]) null);
					if (compositeField != null) {
						parameter = compositeField.lookForParameter(parName
								.substring(i + 1, parName.length()));
					}
				break;
			} else if (parName.charAt(i) == '[') {
				int index = new Integer(parName.substring(i, parName
						.indexOf("]"))).intValue();
				compositeFieldArray = (AbstractData[]) gettersTable.get(
						"get" + parName.substring(0, i)).invoke(this,
						(Object[]) null);
				compositeField = compositeFieldArray[index];
				if (parName.indexOf("]") == (parName.length() - 1)) {
					parameter = compositeField;
				} else {
					if (compositeField != null) {
						parameter = compositeField.lookForParameter(parName
								.substring(parName.indexOf("]" + 1), parName
										.length()));
					}
				}
				break;
			}
			i++;
		} while (i < parName.length());
		if (i == (parName.length())) {
			parameter = gettersTable.get("get" + parName).invoke(this,
					(Object[]) null);

		}
		return parameter;
	}

	public Hashtable<String, Method> getObserversMethodTable() {
		return gettersTable;
	}

	public Hashtable<String, Method> getModifiersMehtodTable() {
		return settersTable;
	}

}
